﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using Gamemaster.Naming;

namespace Gamemaster.Console
{
    public class NameCommand : Command
    {
        public bool Male { get; set; }
        public bool Female { get; set; }
        public int Quantity { get; set; }
        public List<Name> NamesGenerated { get; private set; }

        public NameCommand(params string[] args) : base(args)
        {
            NamesGenerated = new List<Name>();
        }

        public override void PrintHelp()
        {
            base.PrintHelp();

            Out.WriteLine("Name Command: Generated random names.");
            Out.WriteLine();
            Out.WriteLine("Syntax");
            Out.WriteLine("Name [<quantity>] [male] [female] [both] [help]");
            Out.WriteLine();
            Out.WriteLine("quantity:    the number of names to generate (default is 1)");
            Out.WriteLine("male:        include male names (optional)");
            Out.WriteLine("female:      include female names (optional)");
            Out.WriteLine("both:        include both male and female names (this is the default)");
            Out.WriteLine("help:        print this text (optional)");
        }

        protected override void Validate()
        {
            if (Quantity == 0)
            {
                Quantity = 1;
            }

            if (!Male && !Female)
            {
                Male = true;
                Female = true;
            }

            if (Quantity < 1 || Quantity > 100)
            {
                throw new ArgumentOutOfRangeException("Quantity", Quantity, "Must be between 1 and 100");
            }
        }
        protected override void RunCommand()
        {
            GenderOptions options = GenderOptions.Both;
            if (!(Male && Female))
            {
                options = Male ? GenderOptions.Male : GenderOptions.Female;
            }

            NamesGenerated.Clear();
            NamesGenerated.AddRange(Names.Generate(Quantity, options));

            foreach (Name name in NamesGenerated.OrderBy(n => n.Gender).ThenBy(n => n.FirstName))
            {
                Out.WriteLine(name);
            }
        }
        protected override void HandleParameter(Parameter param)
        {
            param.Handled = true;

            switch (param.Value)
            {
                case "name":
                case "names":
                    break;
                case "male":
                    Male = true;
                    break;
                case "female":
                    Female = true;
                    break;
                case "both":
                    Male = true;
                    Female = true;
                    break;
                default:
                    if (Regex.IsMatch(param.Value, "\\d{1,2}"))
                    {
                        Quantity = int.Parse(param.Value);
                    }
                    else
                    {
                        param.Handled = false;
                    }
                    break;
            }
        }
    }
}
